const { ObjectId } = require("mongodb");
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost:27017/";
const dbName = "my_express_server";

function getCollection(collectionName) {
    return new Promise((resolve, reject) => {
        MongoClient.connect(url, function (err, conn) {
            if (err) {
                resolve({
                    msg: "数据库连接失败",
                    err,
                });
            } else {
                const dbOb = conn.db(dbName);
                const collection = dbOb.collection(collectionName);
                resolve({
                    conn,
                    collection,
                });
            }
        });
    });
}

function onResult(resolve, conn, err, result) {
    conn.close();
    resolve({
        err,
        result,
    });
}

/* 添加 */
async function doCreate(collectionName, dataObj) {
    const { err, conn, collection } = await getCollection(collectionName);
    if (err) {
        return Promise.resolve({ err });
    }

    return new Promise((resolve, reject) => {
        collection.insertOne(dataObj, (err, result) =>
            onResult(resolve, conn, err, result)
        );
    });
}

/* 按照条件查询 */
async function doRetrieve(collectionName, whereOption) {
    const { err, conn, collection } = await getCollection(collectionName);
    if (err) {
        return Promise.resolve({ err });
    }

    return new Promise((resolve, reject) => {
        // 如果查询条件含有_id属性 修改user的_id属性修改为对象形式ObjectId(id)
        whereOption._id && (whereOption._id = new ObjectId(whereOption._id));

        collection
            .find(whereOption)
            .toArray((err, result) => onResult(resolve, conn, err, result));
    });
}

/* 修改 */
async function doUpdate(collectionName, id, dataObj) {
    const { err, conn, collection } = await getCollection(collectionName);
    if (err) {
        return Promise.resolve({ err });
    }

    return new Promise((resolve, reject) => {
        collection.updateOne(
            { _id: new ObjectId(id) },
            { $set: dataObj },
            (err, result) => onResult(resolve, conn, err, result)
        );
    });
}

module.exports = {
    doCreate,
    doRetrieve,
    doUpdate,
};
